<template>
  <m-page>
    <template #head>
      <m-navbar title="注册登录" />
    </template>

    <div class="main">
      <!-- logo -->
      <div class="main-header">
        <div class="box-logo">
          <img src="https://static.jsvue.cn/common/assets/logo.192.png" width="70" alt="">
          <span class="website-name">
            <span>{{siteName}}</span>
            <ins>JSVUE.COM</ins>
          </span>
        </div>
        <div class="box-name">
          <template v-if="phoned">
            <h2 class="code-h2">输入短信验证码</h2>
            <span>短信验证码已发送至 {{formatPhone(phone)}}</span>
            <span class="pull-right click-span" @click="phoned = false">修改</span>
          </template>
          <template v-else-if="inviteCode">
            <span>您的微信好友“{{inviteName||'黄老邪'}}”</span>
            <h2>邀请登录{{siteName}}</h2>
          </template>
          <h2 v-else>欢迎登录{{siteName}}</h2>
        </div>
      </div>
      <!-- space-between -->
      <div class="main-flex">
        <div class="main-form">
          <div v-if="!phoned">
            <input v-model="phone" type="tel" maxlength="11" placeholder="请输入电话号码" class="tel-input" @focus="valided = false" @blur="valided = true">
            <span v-if="valided && !validPhone" class="c-msg">手机号码格式错误！请重新输入</span>
            <div class="captcha-input">
              <input v-model="captcha" type="text" maxlength="4" placeholder="请输入右侧验证码" class="tel-input">
              <ClientOnly>
                <van-loading class="img-captcha" v-if="captching" />
                <img v-else-if="imgCaptcha" :src="imgCaptcha" alt="点击刷新" class="img-captcha" @click.stop="refreshCaptchaURL" />
              </ClientOnly>
            </div>
            <van-button block round :loading="loading" :disabled="!validPhone" type="primary" class="submit-btn" @click="handleSubmit">获取短信验证码</van-button>
          </div>
          <div v-else>
            <m-authcode v-model:value="code" :length="6" gutter="16px" focused />
            <div class="code-btn">
              <span class="pull-right click-span">没收到验证码？</span>
              <span v-if="coding">{{ codeTxt }}</span>
              <span v-else class="click-span" @click="handleSubmit">重新发送</span>
            </div>
          </div>
        </div>
        <div class="main-bottom">
          <van-checkbox v-model="agreen"> 同意用户协议</van-checkbox>
          <span class="click-span">《用户服务协议》《隐私政策》</span>
        </div>
      </div>
    </div>
  </m-page>
</template>
<script setup>
import { ref, reactive, toRaw, watch, computed } from 'vue'
import { Base64 } from 'js-base64'
import qs from 'qs'
import Cookies from 'js-cookie'

import { showToast, showLoadingToast, closeToast } from 'vant'

let DTIME
let isLock = null

const route = useRoute()
const router = useRouter()
const agreen = ref(false)
const loading = ref(false)
const captching = ref(false)
const imgCaptcha = ref('') // 验证码路径
const siteName = ref('代码演示库')
const inviteCode = ref('') // 邀请码
const inviteName = ref('') // 邀请人昵称
const valided = ref(false) // 手机号验证状态
const phoned = ref(false) // 获取验证码成功
const scene = 'login'
const phone = ref('')
const captcha = ref('')
const code = ref([])
const coding = ref(false) // 倒计时中
const codeTxt = ref('60s后重新获取')

const $config = useRuntimeConfig()
const { ssrContext } = useNuxtApp()

const stateStr = route.query.state && Base64.decode(route.query.state, true)
const { appid, title, invite, nickname } = qs.parse(stateStr) || { appid: $config.app['APP_ID'], title: $config.app['APP_NAME'] }

siteName.value = title
// 邀请登录
if (invite) {
  inviteCode.value = invite
  inviteName.value = nickname
}
if (ssrContext) { // ssr 代理
  const { data } = await useFetch('/api/common/getCaptcha')
  data.captchaBase64 && (imgCaptcha.value = data.captchaBase64)
} else {
  // 生成验证码
  const data = await getCaptcha({ scene })
  if (data.value && data.value.captchaBase64) imgCaptcha.value = data.value.captchaBase64
}


const formatPhone = computed(() => {
  return function (str) {
    return str.replace(/^(\d{3})(\d{4})(\d{4})$/, '$1 $2 $3').trim()
  }
})
// 手机格式正确
const validPhone = computed(() => {
  const regexp = /^1[3456789](\d|\*){9}$/
  return Boolean(regexp.test(phone.value))
})

const refreshCaptchaURL = () => {
  captching.value = true
  refreshCaptcha({ scene }).then(res => {
    captching.value = false
    const data = res.value
    if (data && data.captchaBase64) {
      imgCaptcha.value = data.captchaBase64
      captcha.value = ''
    }
  })
}

const timer = (num) => {
  DTIME && clearTimeout(DTIME)
  if (num >= 0) {
    coding.value = true
    codeTxt.value = `${num}s重新获取`
    DTIME = setTimeout(() => {
      timer(--num)
    }, 1000)
  } else {
    coding.value = false
    codeTxt.value = '60s重新获取'
  }
}

const handleSubmit = (e) => {
  if (!captcha.value) {
    showToast('请输入图形验证码')
    return
  }
  if (!agreen.value) {
    showToast('请同意以下协议')
    return
  }
  loading.value = true
  sendSmsCode({
    mobile: phone.value,
    captcha: captcha.value,
    scene // loginBySms 默认使用login
  }).then(() => {
    code.value = []
    phoned.value = true
    loading.value = false
    timer(60)
  }).catch(() => {
    refreshCaptchaURL()
    loading.value = false
  })
}

// 验证码登录
const handleLogin = (code) => {
  isLock = true
  showLoadingToast({
    message: '加载中...',
    forbidClick: true
  })
  const param = {
    mobile: phone.value,
    code
  }
  if (inviteCode.value) Object.assign(param, { inviteCode: inviteCode.value })
  loginBySms(param).then(res => {
    const data = res.value
    const { token, tokenExpired, uid } = toRaw(data)
    if (token && uid && tokenExpired) {
      let domain = $config.app['BASE_URL'].slice(-9)
      Cookies.set('OP_ID', uid, { expires: new Date(tokenExpired), domain: domain })
      Cookies.set($config.app['XSRF_HEADER'], token, { expires: new Date(tokenExpired), domain: domain })
      // 返回
      router.back()
    }
    closeToast()
    isLock = false
  }).catch(() => {
    closeToast()
    isLock = false
  })
}

watch(code, (nVal) => {
  const val = nVal.join('')
  if (val.length >= 6 && !isLock) {
    handleLogin(val)
  }
}, { deep: true })

</script>
<style lang="less" scoped>

.main {
  flex: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 0 22px;
  .main-header {
    flex: 0 0 186px;
    .box-logo {
      margin-top: 28px;
      display: inline-flex;
      align-items: center;
      .website-name {
        display: inline-flex;
        flex-direction: column;
        width: 132px;
        margin-left: 10px;
        span {
          font-size: 22px;
          color: #666;
          font-weight: 600;
        }
        ins {
          font-size: 12px;
          text-decoration: unset;
          color: #999;
          text-align: center;
          letter-spacing: 8px;
        }
        ins, span {
          display: block;
          width: 100%;
        }
      }
    }
    .box-name {
      margin-top: 4px;
      padding-left: 2px;
      h2 {
        color: #444;
        font-size: 26px;
        font-weight: 500;
        margin: 0;
      }
    }
  }
  .main-flex {
    flex: 1;
    display: inline-flex;
    flex-direction: column;
    justify-content: space-between;
    .main-form {
      .tel-input {
        width: 100%;
        height: 40px;
        padding-left: 4px;
        font-size: 16px;
        color: #333;
        background-color: unset;
        border: none;
        border-bottom: solid 1px #dedede;
      }
      .c-msg {
        display: inline-block;
        margin-top: 8px;
        font-size: 12px;
        color: #FF442F;
      }
      .captcha-input {
        margin-top: 10px;
        display: flex;
        justify-content: space-between;
        .tel-input {
          flex: 1;
        }
        .img-captcha {
          margin-left: 20px;
          flex: 0 0 100px;
          display: inline-flex;
          justify-content: center;
          align-items: center;
        }
      }

      .submit-btn {
        margin-top: 26px;
        font-size: 16px;
      }

      .code-btn {
        margin-top: 12px;
      }
      .van-password-input {
        margin: 0;
      }
    }
    .main-bottom {
      text-align: center;
      padding-bottom: 22px;
      .van-checkbox {
        justify-content: center;
        margin-bottom: 8px;
      }
    }
  }
  .click-span {
    color: #1989fa;
  }
  .pull-right {
    float: right;
  }
}
</style>
